package com.dashboard.cloud.datasource.service;

import cn.hutool.json.JSONUtil;
import com.alibaba.druid.filter.config.ConfigTools;
import com.dashboard.cloud.datasource.module.EncryptReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.Map;


/**
 * All rights Reserved, Designed By www.super-master.com
 *
 * @ProjectName: spring-cloud-dashboard
 * @Package: com.dashboard.cloud.datasource.service
 * @ClassName: DruidEncryptService
 * @Description: []
 * <p> </p>
 * @Author: [Lance Ting]
 * @Date: 2024/11/8 17:13
 * @Version: V1.0
 * @Copyright: 2024 www.super-master.com Inc. All rights reserved.
 * TODO: 注意,本文件Lance Ting所作,如果转载或使用请标明具体出处!
 **/
@Slf4j
@Service
public class DruidEncryptService {

    public Map<String, Object> encryptPlainText(EncryptReq encryptReq) {
        // 使用工具生成密钥对
        int keySize = 512;
        String[] keyPair = obtainKeyPair(keySize);
        //私钥
        String privateKey = keyPair[0];
        //公钥
        String publicKey = keyPair[1];
        // 用私钥加密后的密文
        String plainText = encryptReq.getPlainText();
        String cipherText = encrypt(privateKey, plainText);
        log.info("\nprivateKey ->  {}\npublicKey ->  {}\nencrypt({}) --> {}", privateKey, publicKey, plainText, cipherText);
        // 公钥解密后的数据
        String decryptText = decrypt(publicKey, cipherText);
        return new HashMap<String, Object>() {
            private static final long serialVersionUID = 4264827912355964447L;

            {
                put("plainText", plainText);
                put("privateKey", privateKey);
                put("cipherText", cipherText);
                put("publicKey", publicKey);
                put("decryptText", decryptText);
            }
        };
    }

    /**
     * 使用私钥对明文进行加密
     *
     * @param privateKey 秘钥
     * @param plainText  明文
     * @return 明文加密后的数据
     */
    private String encrypt(String privateKey, String plainText) {
        try {
            return ConfigTools.encrypt(privateKey, plainText);
        } catch (Exception e) {
            throw new IllegalArgumentException("gen key pair failure,", e);
        }
    }

    /**
     * 使用公钥对密文进行解密
     *
     * @param publicKey  公钥
     * @param cipherText 密文
     * @return 密文解密后的数据
     */
    private String decrypt(String publicKey, String cipherText) {
        try {
            return ConfigTools.decrypt(publicKey, cipherText);
        } catch (Exception e) {
            throw new IllegalArgumentException("gen key pair failure,", e);
        }
    }

    /**
     * 生产密钥对
     *
     * @param keySize 长度
     * @return 秘钥对[秘钥，公钥]
     */
    private String[] obtainKeyPair(int keySize) {
        try {
            // 利用阿里的ConfigTools工具类来生成一对公私钥，私钥用来加密，公钥用来解密
            String[] keyPairs = ConfigTools.genKeyPair(keySize);
            log.info("密钥对: {}", JSONUtil.toJsonStr(keyPairs));
            return keyPairs;
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new IllegalArgumentException("gen key pair failure,", e);
        }
    }
}